﻿
/*
 * Copyright (C) Han Wei
 */


using System;
using System.IO;
using System.Runtime.Remoting;

using BSvr.Model;
using BSvr.PluginAPI;
using System.Reflection;


namespace BSvr.Server
{
    /// <summary>
    /// 插件域对象，插件运行的容器
    /// </summary>
    internal class PluginDomain
    {
        private bool _loaded = false;
        private bool _running = false;
        private string _pluginno = "";
        private string _basepath = "";
        private string _pluginpath = "";
        public AppDomain _domain = null;
        private IPluginProxy _proxy = null;

        /// <summary>
        /// 是否已经加载
        /// </summary>
        public bool Loaded {
            get { return _loaded; }
        }

        /// <summary>
        /// 插件是否已经启动
        /// </summary>
        public bool Running {
            get { return _running; }
        }

        /// <summary>
        /// 插件编号
        /// </summary>
        public string PluginNo {
            get { return _pluginno; }
        }

        /// <summary>
        /// 基目录
        /// </summary>
        public string BasePath {
            get { return _basepath; }
        }

        /// <summary>
        /// 可搜索目录
        /// </summary>
        public string PluginPath {
            get { return _pluginpath; }
        }

        /// <summary>
        /// 插件代理
        /// </summary>
        public IPluginProxy Proxy {
            get { return this._proxy; }
        }

        public PluginDomain(string pluginno, string basepath, string pluginpath) {
            this._pluginno = pluginno;
            this._basepath = (basepath.Trim().EndsWith("\\")?basepath.Trim():(basepath.Trim()+"\\"));
            this._pluginpath = pluginpath;
        }

        /// <summary>
        /// 加载插件
        /// </summary>
        /// <returns></returns>
        public OpRst<string> Load() {
            try
            {
                AppDomainSetup setup = new AppDomainSetup();
                setup.ApplicationBase = this._basepath;
                setup.PrivateBinPath = this._pluginpath;
                if (Directory.Exists(setup.PrivateBinPath))
                {
                    _domain = AppDomain.CreateDomain(this._pluginno, null, setup);

                    int r = 0;
                    if ((r = _domain.ExecuteAssemblyByName("BSvr.PluginProxy")) == 0)
                    {
                        this._loaded = true;
                        return new OpRst<string>(true, r.ToString());
                    }
                    else
                    {
                        this._loaded = false;
                        return new OpRst<string>(false, r.ToString());
                    }
                }
                else
                {
                    this._loaded = false;
                    return new OpRst<string>(false, "插件路径" + setup.PrivateBinPath + "不存在");
                }
            }
            catch (Exception ex)
            {
                this._loaded = false;
                throw ex;
            }
        }

        /// <summary>
        /// 启动插件业务
        /// </summary>
        /// <returns></returns>
        public OpRst<string> Start() {
            try
            {
                if (this._running)
                    return new OpRst<string>(false, "该插件已启动");

                if (_proxy == null)
                {
                    ObjectHandle handle = this._domain.CreateInstance("BSvr.PluginProxy", "BSvr.PluginProxy.Proxy");
                    _proxy = (IPluginProxy)handle.Unwrap();
                }

                OpRst<string> srst = _proxy.Start();
                this._running = srst.IsSuccess;
                return srst;
            }
            catch (Exception ex) {
                this._running = false;
                throw ex;
            }
        }

        /// <summary>
        /// 终止业务插件
        /// </summary>
        /// <returns></returns>
        public OpRst<string> End() {
            try
            {
                if (this._proxy == null || (!this._running))
                {
                    return new OpRst<string>(false, "该插件未启动");
                }

                OpRst<string> erst = _proxy.End();
                this._running = erst.IsSuccess;
                return erst;
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }

        /// <summary>
        /// 卸载业务插件
        /// </summary>
        /// <returns></returns>
        public OpRst<string> UnLoad() {
            try
            {
                AppDomain.Unload(this._domain);
                return new OpRst<string>(true, "");
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }
    }
}
